﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using MongoServices.Tests.TestHelpers;
using MongoServices.Tests.Stubs;
using MongoDB.Bson;

namespace MongoServices.Tests.ReadOnlyRepositoryTests
{
	public class ReadOnlyRepositoryTests : TestBase
	{
		protected ReadOnlyRepository<TestModelSimple> ReadOnlyRepositoryTestModelSimple { get; private set; }

		public ReadOnlyRepositoryTests()
		{
			Setup();
		}

		private void Setup()
		{
			ReadOnlyRepositoryTestModelSimple = new ReadOnlyRepositoryTestModelSimpleStub();
		}
	}

	public class WhenGetAllIsCalled : ReadOnlyRepositoryTests
	{
		[Fact]
		public void AllOfTheAppropriateRecordsAreReturned()
		{
			var testModelCollection = new List<TestModelSimple> {
				new TestModelSimple { TestField = "TestData1" },
				new TestModelSimple { TestField = "TestData2" },
				new TestModelSimple { TestField = "TestData3" }
			};

			testModelCollection.ForEach(m => CollectionTestModelSimple.Save(m));

			var results = ReadOnlyRepositoryTestModelSimple.GetAll();

			Assert.Equal(testModelCollection.Count, results.Count());
			Assert.Equal(testModelCollection.Count, results.Intersect(testModelCollection, new TestModelSimpleEqualityComparer()).Count());
		}
	}

	public class WhenGetByIdIsCalled : ReadOnlyRepositoryTests
	{
		[Fact]
		public void TheAppropriateRecordIsReturned()
		{
			var id1 = ObjectId.GenerateNewId();
			var id2 = ObjectId.GenerateNewId();
			var id3 = ObjectId.GenerateNewId();

			var testModelCollection = new List<TestModelSimple> {
				new TestModelSimple { Id = id1, TestField = "TestData1" },
				new TestModelSimple { Id = id2, TestField = "TestData2" },
				new TestModelSimple { Id = id3, TestField = "TestData3" }
			};

			testModelCollection.ForEach(m => CollectionTestModelSimple.Save(m));

			var results = ReadOnlyRepositoryTestModelSimple.GetById(id1);

			Assert.Equal(testModelCollection.First(m => m.Id == id1), results, new TestModelSimpleWithIdEqualityComparer());
		}

		[Fact]
		public void ReturnsNullWhenTheIdDoesNotExist()
		{
			var testModel = new TestModelSimple { TestField = "TestData" };

			CollectionTestModelSimple.Save(testModel);

			var results = ReadOnlyRepositoryTestModelSimple.GetById(ObjectId.GenerateNewId());

			Assert.Null(results);
		}
	}
}
